﻿var ListProductsRAW;
jQuery(document).ready(function () {
    $.fn.renderCanvas = function (options) {
        var defaults = {
            type: '',
            dialog: "",
            clienteID: "",
            ulProducts: "",
            dtStart: "",
            dtEnd: ""
        }
        options = $.extend(defaults, options);
        return this.each(function () {
            var ListProducts = new Array();
            var canvas;
            var context;
            /*
                GProduct = {
                    ProductID: 0,
                    ProductColor: '',
                    ProductName: '',
                    ProductHeight: 0
                }
            */
            var TagType = $(this)[0].tagName;
            if (TagType == 'CANVAS' && options.dialog != "") {
                $('#' + options.dialog).dialog('open');
                canvas = $(this)[0];
                context = canvas.getContext("2d");
                ListProductsRAW = getProducts();
                transferProducts();
                resetCanvas();
                if (options.type === '0') {/*this type is when the graph is of the Bar Type */
                    drawBars();
                } else if (options.type === '1') {/*this type is when graph is Cake Type */
                    drawCircle();
                } else if (options.type == '2') {/*this type is when graph is Line Type */
                    drawPoints();
                }
                generateProductList();

            } else {
                alert('no todos los parametros han sido insertados');
            }

            function getProducts() {
                var parametros = {
                    dtStart: options.dtStart,
                    dtEnd: options.dtEnd
                };
                var url = "";
                if (options.type == 2) {
                    if (options.clienteID != "") {
                        parametros.clienteID = options.clienteID;
                        url = "Index.aspx/ListDatesByClient";
                    } else {
                        url = "Index.aspx/ListDates";
                    }
                } else {
                    if (options.clienteID != "") {
                        parametros.clienteID = options.clienteID;
                        url = "Index.aspx/ListProductsByClient";
                    } else {
                        url = "Index.aspx/ListProducts";
                    }
                }
                var paramString = JSON.stringify(parametros);
                var result = '';
                $.ajax({
                    url: url,
                    async: false,
                    data: paramString,
                    dataType: 'json',
                    type: 'POST',
                    contentType: 'application/json; charset=utf-8',
                    success: function (data) {
                        result = data.d;
                    },
                    error: function (data) {
                        var aux = data.d;
                    }
                });
                return result;
            }

            function generateProductList() {
                if (options.ulProducts != "" && ListProducts != undefined && ListProducts.length > 0) {
                    var ul = $('#' + options.ulProducts);
                    ul.css({
                        'list-style': 'none',
                        'margin': 0,
                        'padding': 0
                    });
                    for (var i = 0; i < ListProducts.length; i++) {
                        ul.append('<li style="display: inline-block; margin-right: 5px; "><a style="padding: 0px 12px 0px 8px; background:' + ListProducts[i].ProductColor + ';"></a><a style="padding: 5px;  font-family:\'Didact Gothic\', sans-serif; font-size: 15px;">' + ListProducts[i].ProductName + ' ' + CantToPercentage(i) + '</a></li>');
                    }
                }
            }

            function sumTotal() {
                var sumTotal = 0;
                for (var i = 0; i < ListProducts.length; i++) {
                    sumTotal += ListProducts[i].ProductHeight;
                }
                return sumTotal;
            }

            function CantToPercentage(i) {
                var Percentage = 0;
                if (options.type == 1) {
                    var aux = ListProducts[i].ProductHeight;
                    Percentage = Math.round((100 * (aux / 360)));
                    Percentage += '%';
                } else if (options.type == 0) {
                    //var total = sumTotal();
                    Percentage = ListProductsRAW[i].ProductHeight;//(100 * (variable / total));
                } else if (options.type == 2) {
                    Percentage = "";
                }
                return Percentage;
            }

            function drawCircle() {
                CantToDeg();
                for (var i = 0; i < ListProducts.length; i++) {
                    drawAngle(i);
                }
                function DegToRad(degree) {
                    return (degree * Math.PI) / 180;
                }
                function CantToDeg() {
                    // n / 360 = ListProducts[i].ProductHeight/total
                    var total = sumTotal();
                    for (var i = 0; i < ListProducts.length; i++) {
                        var degree = (360 * ListProducts[i].ProductHeight) / total;
                        ListProducts[i].ProductHeight = degree;
                    }
                }
                function drawAngle(i) {
                    var canvasCoord = {
                        x: Math.floor(canvas.width / 2),
                        y: Math.floor(canvas.height / 2)
                    };
                    var radius = Math.floor(canvas.height / 2);
                    var CircleStat = {
                        start: 0,
                        end: 0
                    }
                    CircleStat.start = DegToRad(getAccAngle(i));
                    CircleStat.end = (CircleStat.start + DegToRad(ListProducts[i].ProductHeight));
                    context.beginPath();
                    context.moveTo(canvasCoord.x, canvasCoord.y);
                    context.arc(canvasCoord.x, canvasCoord.y, radius,
                                CircleStat.start, CircleStat.end, false);
                    context.closePath();
                    context.fillStyle = ListProducts[i].ProductColor;
                    context.fill();
                }
                function getAccAngle(i) {
                    var sumAngle = 0;
                    for (var j = 0; j < i; j++) {
                        sumAngle += ListProducts[j].ProductHeight;
                    }
                    return sumAngle;
                }
            }

            function drawBars() {
                var maxHeight = determineHeight();
                var maxCanvas = Math.floor(canvas.height - 10);
                cantToScale(maxHeight, maxCanvas);
                var RecStats = {
                    x: 50,
                    width: 20
                }
                for (var i = 0; i < ListProducts.length; i++) {
                    drawBarSegment(i, RecStats.x);
                    RecStats.x += RecStats.width + 10;
                }
                setGraphLines();
                drawNumberLines(maxHeight, maxCanvas);
                function drawBarSegment(i, x) {
                    var y = canvas.height - ListProducts[i].ProductHeight;
                    drawRectangle(x, y, RecStats.width, ListProducts[i].ProductHeight, ListProducts[i].ProductColor);
                }


            }

            function drawPoints() {
                var maxHeight = determineHeight();
                var maxCanvas = Math.floor(canvas.height - 10);
                cantToScale(maxHeight, maxCanvas);
                var RecStats = {
                    x: 50
                }
                var PointStat = {
                    xOffset: 1,
                    yOffset: 1,
                    radius: 4
                }
                drawNumberLines(maxHeight, maxCanvas);
                drawPointLines();
                for (var i = 0; i < ListProducts.length; i++) {
                    drawPointSegment(i, RecStats.x);
                    RecStats.x += 50;
                }
                setGraphLines();
                function drawPointSegment(i, x) {
                    var y = canvas.height - ListProducts[i].ProductHeight;
                    drawPoint(x + PointStat.xOffset, y + PointStat.yOffset, PointStat.radius, ListProducts[i].ProductColor);
                }

                function drawPointLines() {
                    var x = 50;
                    if (ListProducts.length > 1) {
                        for (var i = 0; i < ListProducts.length; i++) {
                            var test = i + 1;
                            if (test < ListProducts.length) {
                                var y = canvas.height - ListProducts[i].ProductHeight;
                                var y2 = canvas.height - ListProducts[i + 1].ProductHeight;
                                drawLine(x, y, x + 50, y2, "#000");
                            }
                            x += 50;
                        }
                    }
                }

                function drawPoint(x, y, radius, color) {
                    context.beginPath();
                    context.arc(x, y, radius, 0, 2 * Math.PI, false);
                    context.fillStyle = color;
                    context.fill();
                    context.lineWidth = 1;
                    context.strokeStyle = '#000';
                    context.stroke();
                }
            }

            function cantToScale(maxHeight, maxCanvas) {
                for (var i = 0; i < ListProducts.length; i++) {
                    var aux = ListProducts[i].ProductHeight;
                    var scale = (maxCanvas * ListProducts[i].ProductHeight) / maxHeight;
                    ListProducts[i].ProductHeight = scale;
                }
            }

            function setGraphLines() {
                var color = "#000";
                drawLine(0, 0, 0, canvas.height, color);
                drawLine(0, canvas.height, canvas.width, canvas.height, color);
            }

            function drawLine(x1, y1, x2, y2, lineColor) {
                context.beginPath();
                context.lineWidth = 1;
                context.moveTo(x1, y1);
                context.lineTo(x2, y2);
                context.closePath();
                context.strokeStyle = lineColor;
                context.stroke();
            }

            function drawRectangle(x, y, width, height, recColor) {
                context.beginPath();
                context.rect(x, y, width, height);
                context.fillStyle = recColor;
                context.fill();
                context.closePath();
            }

            function resetCanvas() {
                context.beginPath();
                context.rect(0, 0, canvas.width, canvas.height);
                context.fillStyle = "#fff";
                context.fill();
                context.closePath();
            }

            function transferProducts() {
                for (var i = 0; i < ListProductsRAW.length; i++) {
                    ListProducts.push({
                        ProductID: ListProductsRAW[i].ProductID,
                        ProductColor: ListProductsRAW[i].ProductColor,
                        ProductName: ListProductsRAW[i].ProductName,
                        ProductHeight: ListProductsRAW[i].ProductHeight
                    });
                }
            }

            function drawNumberLines(maxHeight, maxCanvas) {
                var div = gcd(maxCanvas, maxHeight);
                var interval = (maxCanvas / div);
                var counter = 0;
                var sumInterval = interval;
                var color = "#000";
                var font = "12px Arial";
                var ylabel = 14;
                var linelength = 5;
                for (var i = canvas.height; i >= 0; i--) {
                    if (counter === sumInterval) {
                        var y = i;
                        //drawThinHorizontal(0, linelength, y-1, color);
                        drawThinHorizontal(0, linelength, y, color);
                        drawLabel(5, y + ylabel, font, color, ScaleToCant(sumInterval, maxHeight, maxCanvas));
                        sumInterval += interval;
                    }

                    if (containsCant(ListProducts, counter)) {
                        var y = i;
                        var array = getCant(counter);
                        drawThinHorizontal(0, linelength, y, color);
                        if (array != null && array != undefined && array.length > 0) {
                            drawDottedThinHorizontal(10, canvas.width, y, 10, 7, "#555");
                            drawLabel(5, y + ylabel, font, color, ScaleToCant(array[0].ProductHeight, maxHeight, maxCanvas));
                        }
                        //sumInterval += interval;
                    }
                    counter++;
                }
            }
            function gcd(a, b) {
                if (a < 0) a = -a;
                if (b < 0) b = -b;
                if (b > a) { var temp = a; a = b; b = temp; }
                while (true) {
                    a %= b;
                    if (a == 0) return b;
                    b %= a;
                    if (b == 0) return a;
                }
            }

            function drawThinHorizontal(x1, x2, y, color) {
                context.lineWidth = 1;
                context.strokeStyle = color;
                var adaptedY = Math.floor(y) + 0.5;
                context.beginPath();
                context.moveTo(x1, adaptedY);
                context.lineTo(x2, adaptedY);
                context.stroke();
                context.closePath();
            }

            function drawDottedThinHorizontal(x1, x2, y, lengthDot, lengthSpace, color) {
                context.lineWidth = 1;
                context.strokeStyle = color;
                var adaptedY = Math.floor(y) + 0.5;
                var spacing = lengthSpace;
                var i = x1;
                while (i < x2) {
                    context.beginPath();
                    context.moveTo(i, adaptedY);
                    context.lineTo(i + lengthDot, adaptedY);
                    context.stroke();
                    context.closePath();
                    i += lengthSpace + lengthDot;
                }

            }

            function containsCant(arrayProducts, cant) {
                if (ListProducts != undefined && ListProducts.length > 0) {
                    for (var i = 0; i < ListProducts.length; i++) {
                        if (Math.floor(ListProducts[i].ProductHeight) == cant) {
                            return true;
                        }
                    }
                }
                return false;
            }

            function getCant(cant) {
                var arrayProducts = new Array();
                /*
                ListProducts.push({
                        ProductHeight: ListProductsRAW[i].ProductHeight
                    });
                */
                for (var i = 0; i < ListProducts.length; i++) {
                    if (Math.floor(ListProducts[i].ProductHeight) == cant) {
                        if (!isCantInArray(arrayProducts, ListProducts[i].ProductHeight)) {
                            arrayProducts.push({
                                ProductHeight: ListProducts[i].ProductHeight
                            });
                        }
                    }
                }
                return arrayProducts;
            }

            function isCantInArray(array, exact_cant) {
                if (array != null && array != undefined && array.length > 0 && exact_cant != null && exact_cant != undefined && exact_cant >= 0) {
                    for (var i = 0; i < array.length; i++) {
                        if (array.ProductHeight === exact_cant) {
                            return true;
                        }
                    }
                }
                return false;
            }


            function determineHeight() {
                var tallestBar = 0;
                for (var i = 0; i < ListProducts.length; i++) {
                    if (ListProducts[i].ProductHeight > tallestBar) {
                        tallestBar = ListProducts[i].ProductHeight;
                    }
                }
                var aux = tallestBar * 0.10;
                //return Math.floor(tallestBar + aux);
                return tallestBar;
            }

            function drawLabel(x, y, font, color, text) {
                context.beginPath();
                context.font = font;
                context.fillStyle = color;
                context.fillText(text, x, y);
                context.closePath();
            }

            function ScaleToCant(scaleVariable, maxHeight, maxCanvas) {
                return (maxHeight * (scaleVariable / maxCanvas));
            }

            function determineOriginalHeight() {
                var height = 0;
                for (var i = 0; i < ListProductsRAW.length; i++) {
                    if (ListProductsRAW[i].ProductHeight > height) {
                        height = ListProductsRAW[i].ProductHeight;
                    }
                }
                return height;
            }
        });
    }
});